/*  CryptoServer - secure online voting server
    Copyright (C) 2004  The Adder Team

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/**
 * @file main.cc
 * Contains main program routines.
 */
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>

#include <fstream>
#include <string>
#include <vector>

#include "ClientHandler.hh"
#include "Options.hh"

#include "popt.h"

#undef VERSION
#undef VERSION
#undef PACKAGE
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
#undef PACKAGE_STRING
#undef PACKAGE_TARNAME
#undef PACKAGE_VERSION
#include "config.h"

int got_sighup = 0;


/**
 * Signal handler for the SIGINT signal.
 * @param i unused parameter for signal handlers.
 */
extern "C" void sigint_handler(int i)
{
    /* Print shutdown message. */
    DEBUG(("SHUTDOWN: got sigint... shutting down server daemon\n"));

    exit(0);
}

extern "C" void sighup_handler(int i)
{
    got_sighup = 1;

    OPTIONS->read_config_files();
}

static void print_version()
{
    std::cout << "version " << PACKAGE_VERSION << std::endl;
}

/**
 * Main function.
 * @param argc number of command-line arguments.
 * @param argv array of command-line arguments.
 */
int main(int argc, char** argv)
{
    std::string conffile;

    /*
     * FIXME: The logger is not set up at this point, so DEBUG
     * prints to stdout.
     */
#if 0
    DEBUG(("DEBUG: reading config files\n"));
#endif

    OPTIONS->parse(argc, argv, conffile);

    if (!OPTIONS->read_config_files()) {
#if 0
        DEBUG(("ERROR: error reading config files\n"));
#endif
    }

    int daemon_mode = 0;
    int version = 0;

    static struct poptOption optionsTable[] = {
        { "daemon", 'd', POPT_ARG_NONE, &daemon_mode, 0, "Use daemon mode", NULL },
        { "version", 'v', POPT_ARG_NONE, &version, 0, "Display cryptoserver version", NULL },
        POPT_AUTOHELP
        POPT_TABLEEND
    };

    poptContext optCon = poptGetContext(argv[0], argc, const_cast<const char**>(argv), optionsTable, 0);

    int rc = poptGetNextOpt(optCon);

    if (rc < -1) {
        std::cerr << poptBadOption(optCon, rc) << ": " << poptStrerror(rc) << std::endl;
        return rc;
    }

    poptFreeContext(optCon);

    if (version == 1) {
        print_version();
        return 0;
    }

    if (daemon_mode == 1) {
        OPTIONS->daemon = true;
        OPTIONS->logging = "syslog";
    }

    if (OPTIONS->daemon) {
        /* Print startup message. */
        DEBUG(("STARTUP: starting up server as daemon\n"));

#if HAVE_DAEMON
        if (daemon(1, 1) < 0) {
            DEBUG(("ERROR: error making daemon\n"));
        }
#else
        DEBUG(("WARNING: daemon() not supported\n"));
#endif

        std::ofstream pidfile(PID_FILE);

        if (!pidfile) {
            DEBUG(("ERROR: error creating pid file: %s\n", PID_FILE));
        }

        DEBUG(("INFO: pidfile: %s\n", PID_FILE));

        pidfile.close();
    } else {
        DEBUG(("STARTUP: starting up server not as daemon\n"));
    }

	
    /* Register the SIGINT signal handler. */
    signal(SIGINT, sigint_handler);

    /* Register the SIGHUP signal handler. */
    signal(SIGHUP, sighup_handler);


    ClientHandler::initialize_function_map();
    ClientHandler clhandler;

    clhandler.openUdpConnection();


    /* Print shutdown message. */
    DEBUG(("SHUTDOWN: shutting down server...\n"));

    return 0;
}
